package com.immunology.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.immunology.core.BaseDao;
import com.immunology.core.BaseTransformer;
import com.immunology.core.GenericDao;
import com.immunology.database.DbColumns;
import com.immunology.model.Complaint;
import com.immunology.model.ComplaintType;
import com.immunology.model.Syndrome;
import com.immunology.service.ComplaintTypeService;
import com.immunology.service.SyndromeService;

public class ComplaintDao extends BaseDao<Complaint> implements
		GenericDao<Complaint> {

	private List<Complaint> complaintList = null;
	private List<Syndrome> syndromeList = null;

	public ComplaintDao(BaseTransformer<Complaint> transformer) {
		super(transformer, new String("COMPLAINT"));
	}

	@Override
	public void insert(Complaint complaint) {
		Connection connection = connectionManager.getConnection();
		StringBuilder query = new StringBuilder();
		query.append("INSERT INTO ");
		query.append(tableName);
		query.append(" (NAME, TYPE_ID)");
		query.append(" VALUES(?, ?)");
		try {
			PreparedStatement preparedStatement = (PreparedStatement) connection
					.prepareStatement(query.toString());
			preparedStatement.setString(DbColumns.FIRST_COLUMN,
					complaint.getName());
			preparedStatement.setInt(DbColumns.SECOND_COLUMN,
					complaint.getTypeId());
			preparedStatement.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			connectionManager.closeConnection(connection);
		}
	}

	@Override
	public void update(int complaintId, Complaint complaint) {
		Connection connection = connectionManager.getConnection();
		StringBuilder query = new StringBuilder();
		query.append("UPDATE ");
		query.append(tableName);
		query.append(" SET NAME = ?");
		query.append(" WHERE ID = ?");
		try {
			PreparedStatement preparedStatement = (PreparedStatement) connection
					.prepareStatement(query.toString());
			preparedStatement.setString(DbColumns.FIRST_COLUMN,
					complaint.getName());
			preparedStatement
					.setInt(DbColumns.SECOND_COLUMN, complaint.getId());
			preparedStatement.executeUpdate();

			preparedStatement.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			connectionManager.closeConnection(connection);
		}
	}

	public Map<String, Map<String, List<Complaint>>> getComplaintList() {
		this.getDataFromDatabase();
		return this.getComplaintListFromDatabase();
	}

	public Map<String, Map<String, List<Complaint>>> getComplaintListBySyndromeId(
			int syndromeId) {
		this.getDataFromDatabase(syndromeId);
		return this.getComplaintListFromDatabase();
	}

	private Map<String, Map<String, List<Complaint>>> getComplaintListFromDatabase() {
		Map<String, Map<String, List<Complaint>>> syndromeMap = new HashMap<String, Map<String, List<Complaint>>>();
		Map<String, List<Complaint>> complaintTypeMap = null;
		Iterator<Syndrome> syndromeIterator = syndromeList.iterator();
		while (syndromeIterator.hasNext()) {
			complaintTypeMap = new HashMap<String, List<Complaint>>();
			Syndrome syndrome = syndromeIterator.next();
			int syndromeId = syndrome.getId();
			List<ComplaintType> currentSyndromComplaintTypeList = this
					.getComplaintTypeListBySyndromeId(syndromeId);
			Iterator<ComplaintType> complaintTypeIterator = currentSyndromComplaintTypeList
					.iterator();
			while (complaintTypeIterator.hasNext()) {
				ComplaintType complaintType = complaintTypeIterator.next();
				int complaintTypeId = complaintType.getId();
				List<Complaint> complaints = this
						.getComplaintListByComplaintTypeId(complaintTypeId);
				complaintTypeMap.put(complaintType.getName(), complaints);
			}
			syndromeMap.put(syndrome.getName(), complaintTypeMap);
		}
		return syndromeMap;
	}

	private void getDataFromDatabase() {
		SyndromeService syndromeService = SyndromeService.getInstance();
		syndromeList = syndromeService.getSyndromeList();
		complaintList = this.getAll();
	}

	private void getDataFromDatabase(int syndromeId) {
		SyndromeService syndromeService = SyndromeService.getInstance();
		syndromeList = new ArrayList<Syndrome>();
		syndromeList.add(syndromeService.getSyndromeById(syndromeId));
		complaintList = this.getAll();

	}

	private List<ComplaintType> getComplaintTypeListBySyndromeId(int syndromeId) {
		ComplaintTypeService complaintTypeService = ComplaintTypeService
				.getInstance();
		return complaintTypeService
				.getComplaintTypeListBySyndromeId(syndromeId);
	}

	private List<Complaint> getComplaintListByComplaintTypeId(
			int complaintTypeId) {
		List<Complaint> list = new ArrayList<Complaint>();
		Iterator<Complaint> iterator = complaintList.iterator();
		while (iterator.hasNext()) {
			Complaint complaint = iterator.next();
			if (complaintTypeId == complaint.getTypeId()) {
				list.add(complaint);
			}
		}
		return list;
	}

	public int getComplaintTypeIdByComplaintId(int complaintId) {
		int result = 0;

		Connection connection = connectionManager.getConnection();
		ResultSet resultSet = null;
		StringBuilder query = new StringBuilder();
		query.append("SELECT type_id FROM ");
		query.append(tableName);
		query.append(" WHERE id = " + complaintId);
		try {
			Statement statement = connection.createStatement();
			resultSet = statement.executeQuery(query.toString());
			while (resultSet.next()) {
				result = resultSet.getInt(DbColumns.FIRST_COLUMN);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			connectionManager.closeConnection(connection);
		}

		return result;
	}

}
